home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / bench / sun4.md / printStats.c < prev   
C/C++ Source or Header  |  1991-10-09  |  27KB  |  776 lines

  1. /*
  2.  * printStats.c --
  3.  *    Routines to print out program execution times, and filesystem stats.
  4.  */
  5.  
  6. #include "sprite.h"
  7. #include "status.h"
  8. #include "sys/ioctl.h"
  9. #include "sys/file.h"
  10. #include "stdio.h"
  11. #include "proc.h"
  12. #include "vm.h"
  13. #include "sysStats.h"
  14. #include "kernel/fs.h"
  15. #include "kernel/fsStat.h"
  16. #include "kernel/sched.h"
  17. #include "kernel/vm.h"
  18. #include "kernel/net.h"
  19.  
  20.  
  21.  
  22. /*
  23.  *----------------------------------------------------------------------
  24.  *
  25.  * PrintTimes --
  26.  *
  27.  *    Print the resource usage (user and kernel CPU time) and elapsed time.
  28.  *
  29.  * Results:
  30.  *    None.
  31.  *
  32.  * Side effects:
  33.  *    Prints to the specified stream
  34.  *
  35.  *----------------------------------------------------------------------
  36.  */
  37. void
  38. PrintTimes(stream, usagePtr, timePtr)
  39.     FILE *stream;
  40.     Proc_ResUsage *usagePtr;
  41.     Time *timePtr;
  42. {
  43.     Time delta;
  44.     if (usagePtr != NULL) {
  45.     Time_Add(usagePtr->userCpuUsage, usagePtr->childUserCpuUsage,
  46.                      &delta);
  47.     fprintf(stream, "%d.%03du ", delta.seconds,
  48.                    delta.microseconds / 1000);
  49.     Time_Add(usagePtr->kernelCpuUsage, usagePtr->childKernelCpuUsage,
  50.                      &delta);
  51.     fprintf(stream, "%d.%03ds ", delta.seconds,
  52.                    delta.microseconds / 1000);
  53.     }
  54.     if (timePtr != NULL) {
  55.     int seconds = timePtr->seconds;
  56.     if (seconds >= 3600) {
  57.         fprintf(stream, "%d:", seconds / 3600);
  58.         seconds = seconds % 3600;
  59.     }
  60.     if (seconds >= 60) {
  61.         fprintf(stream, "%d:", seconds / 60);
  62.         seconds = seconds % 60;
  63.     }
  64.     fprintf(stream, "%d.%03d", seconds,
  65.                    timePtr->microseconds / 1000);
  66.     }
  67.     fprintf(stream, "\n");
  68. }
  69.  
  70.  
  71. /*
  72.  *----------------------------------------------------------------------
  73.  *
  74.  * PrintIdleTime --
  75.  *
  76.  *    Given two samples sched module statistics, this computes
  77.  *    the differenc in idle ticks and, using the time, computes
  78.  *    a utilization.
  79.  *
  80.  * Results:
  81.  *    None.
  82.  *
  83.  * Side effects:
  84.  *    Prints to the specified stream
  85.  *
  86.  *----------------------------------------------------------------------
  87.  */
  88. void
  89. PrintIdleTime(stream, startSchedPtr, endSchedPtr, timePtr)
  90.     FILE *stream;
  91.     Sched_Instrument *startSchedPtr, *endSchedPtr;
  92.     Time *timePtr;
  93. {
  94.     register     highTicks;
  95.     double     lowTicks;
  96.     int        cpu;
  97.  
  98.     Sched_Instrument zeroStats;
  99.     if (startSchedPtr == NULL) {
  100.     bzero(&zeroStats, sizeof(Sched_Instrument));
  101.     startSchedPtr = &zeroStats;
  102.     }
  103.  
  104.     for (cpu=0; cpu<MACH_MAX_NUM_PROCESSORS; cpu++) {
  105.         highTicks = endSchedPtr->processor[cpu].idleTicksOverflow -
  106.         startSchedPtr->processor[cpu].idleTicksOverflow;
  107.         lowTicks = endSchedPtr->processor[cpu].idleTicksLow 
  108.         - startSchedPtr->processor[cpu].idleTicksLow;
  109.  
  110.         if (highTicks != 0) {
  111.         fprintf(stream, "(High ticks = %d)", highTicks);
  112.         }
  113.         if (timePtr->seconds == 0 && timePtr->microseconds == 0) {
  114.         fprintf(stream, "Idle ticks --/-- = 100%% Idle, Elapsed time ");
  115.         } else {
  116.         lowTicks /= 
  117.           (double)timePtr->seconds 
  118.             + (double) (timePtr->microseconds)/1000000.;
  119.         fprintf(stream, "Idle ticks %0.0f/%d = %6.2f%% Idle, Context Sw. %d inv %d full %d, Elapsed time ",
  120.                    lowTicks,
  121.             endSchedPtr->processor[cpu].idleTicksPerSecond,
  122.             (double)lowTicks/(double)endSchedPtr->processor[cpu].idleTicksPerSecond * 100.,
  123.             endSchedPtr->processor[cpu].numContextSwitches 
  124.                 - startSchedPtr->processor[cpu].numContextSwitches,
  125.                    endSchedPtr->processor[cpu].numInvoluntarySwitches 
  126.                 - startSchedPtr->processor[cpu].numInvoluntarySwitches,
  127.                    endSchedPtr->processor[cpu].numFullCS 
  128.                 - startSchedPtr->processor[cpu].numFullCS);
  129.         }
  130.         PrintTimes(stream, (Proc_ResUsage *)0, timePtr);
  131.     }
  132. }
  133.  
  134.  
  135. /*
  136.  *----------------------------------------------------------------------
  137.  *
  138.  * PrintFsStats --
  139.  *
  140.  *    Print out the filesystem statistics.  If both a start and end
  141.  *    sample of the statistics are given then the differences between
  142.  *    the two are printed.  To just print the total cumulative statistics
  143.  *    from one sample, specify a single Fs_Stats buffer with the 'end'
  144.  *    parameter.
  145.  *
  146.  * Results:
  147.  *    None.
  148.  *
  149.  * Side effects:
  150.  *    Prints to the specified stream
  151.  *
  152.  *----------------------------------------------------------------------
  153.  */
  154. void
  155. PrintFsStats(stream, start, end, verbose)
  156.     FILE *stream;    /* Output stream */
  157.     Fs_Stats *start;    /* 0, or address of "before run" statistics */
  158.     Fs_Stats *end;    /* End of run statistics */
  159.     int verbose;    /* If true, everything is dumped */
  160. {
  161.     register int t1, t2, t3, t4, t5;
  162.     Fs_Stats zeroStats;
  163.  
  164.     if (start == (Fs_Stats *)0) {
  165.     bzero(&zeroStats, sizeof(Fs_Stats));
  166.     start = &zeroStats;
  167.     }
  168.     /*
  169.      * Print cache size
  170.      */
  171.     fprintf(stream, "Cache blocks max %d min %d number %d/%d free %d/%d limit %d\n",
  172.                end->blockCache.maxCacheBlocks,
  173.                end->blockCache.minCacheBlocks,
  174.                start->blockCache.numCacheBlocks,
  175.                end->blockCache.numCacheBlocks,
  176.                start->blockCache.numFreeBlocks,
  177.                end->blockCache.numFreeBlocks,
  178.                end->blockCache.maxNumBlocks);
  179.  
  180.     /*
  181.      * Print bytes read traffic ratio
  182.      */
  183.     t1 = end->blockCache.bytesRead - start->blockCache.bytesRead;
  184.     t2 = end->blockCache.dirBytesRead - start->blockCache.dirBytesRead;
  185.     t3 = end->gen.remoteBytesRead - start->gen.remoteBytesRead;
  186.     t4 = end->gen.fileBytesRead - start->gen.fileBytesRead;
  187.     t5 = end->gen.physBytesRead - start->gen.physBytesRead;
  188.     fprintf(stream, "Bytes read %d+%d remote %d disk %d+%d",
  189.                t1, t2, t3, t4, t5);
  190.     if (t1 + t2 > 0) {
  191. #ifdef stupid_compiler
  192.     fprintf(stream, "\ttraffic ratio %%%d\n",
  193.                (int)((double)(t3+t4+t5)/(double)(t1+t2) * 100.));
  194. #else
  195.     fprintf(stream, "\n");
  196. #endif
  197.     } else {
  198.     fprintf(stream, "\n");
  199.     }
  200.  
  201.     /*
  202.      * Print bytes written traffic ratio
  203.      */
  204.     t1 = end->blockCache.bytesWritten - start->blockCache.bytesWritten +
  205.     (end->blockCache.fileDescWrites - start->blockCache.fileDescWrites +
  206.      end->blockCache.indBlockWrites - start->blockCache.indBlockWrites) *
  207.     FS_BLOCK_SIZE;
  208.     t2 = end->blockCache.dirBytesWritten - start->blockCache.dirBytesWritten;
  209.     t3 = end->gen.remoteBytesWritten - start->gen.remoteBytesWritten;
  210.     t4 = end->gen.fileBytesWritten - start->gen.fileBytesWritten;
  211.     t5 = end->gen.physBytesWritten - start->gen.physBytesWritten;
  212.     fprintf(stream, "Bytes written %d+%d remote %d disk %d+%d",
  213.                t1, t2, t3, t4, t5);
  214. #ifdef stupid_compiler
  215.     if (t1 + t2 > 0) {
  216.     fprintf(stream, "\ttraffic ratio %%%d",
  217.                (int)((double)(t3+t4+t5)/(double)(t1+t2) * 100.));
  218.     }
  219. #endif
  220.     fprintf(stream, "\n");
  221.  
  222.     if (verbose) {
  223.     /*
  224.      * Print device bytes and zero fills
  225.      */
  226.     t1 = end->gen.deviceBytesWritten - start->gen.deviceBytesWritten;
  227.     t2 = end->gen.deviceBytesRead - start->gen.deviceBytesRead;
  228.     fprintf(stream, "Dev bytes read %d written %d\n", t1, t2);
  229.     t1 = end->blockCache.readZeroFills - start->blockCache.readZeroFills;
  230.     t2 = end->blockCache.writeZeroFills1 -
  231.         start->blockCache.writeZeroFills1;
  232.     t3 = end->blockCache.writeZeroFills2 -
  233.         start->blockCache.writeZeroFills2;
  234.     t4 = end->blockCache.fragZeroFills - start->blockCache.fragZeroFills;
  235.     fprintf(stream, "Zero Fills read %d write1 %d write2 %d frag %d\n",
  236.                    t1, t2, t3, t4);
  237.     t1 = end->blockCache.appendWrites - start->blockCache.appendWrites;
  238.     t2 = end->blockCache.overWrites - start->blockCache.overWrites;
  239.     t3 = end->blockCache.domainReadFails -
  240.         start->blockCache.domainReadFails;
  241.     fprintf(stream, "Appends %d Overwrites %d Failed Reads %d\n",
  242.                    t1, t2, t3);
  243.     }
  244.     t1 = end->blockCache.readAccesses - start->blockCache.readAccesses +
  245.      end->blockCache.fragAccesses - start->blockCache.fragAccesses +
  246.      end->blockCache.fileDescReads - start->blockCache.fileDescReads +
  247.      end->blockCache.indBlockAccesses - start->blockCache.indBlockAccesses +
  248.      end->blockCache.dirBlockAccesses - start->blockCache.dirBlockAccesses;
  249.     t2 = end->blockCache.readHitsOnDirtyBlock -
  250.     start->blockCache.readHitsOnDirtyBlock;
  251.     t3 = end->blockCache.readHitsOnCleanBlock -
  252.     start->blockCache.readHitsOnCleanBlock;
  253.     t4 = end->blockCache.fragHits - start->blockCache.fragHits +
  254.      end->blockCache.fileDescReadHits - start->blockCache.fileDescReadHits +
  255.      end->blockCache.indBlockHits - start->blockCache.indBlockHits +
  256.      end->blockCache.dirBlockHits - start->blockCache.dirBlockHits;
  257.     fprintf(stream, "Cache reads %d hits: dirty %d clean %d other %d",
  258.                t1, t2, t3, t4);
  259. #ifdef stupid_compiler
  260.     if (t1 != 0) {
  261.     fprintf(stream, "\thit ratio %%%d",
  262.                (int)((double)(t2+t3+t4)/(double)t1 * 100.));
  263.     }
  264. #endif
  265.     fprintf(stream, "\n");
  266.  
  267.     t1 = end->blockCache.readAheads - start->blockCache.readAheads;
  268.     t2 = end->blockCache.readAheadHits - start->blockCache.readAheadHits;
  269.     t3 = end->blockCache.allInCacheCalls - start->blockCache.allInCacheCalls;
  270.     t4 = end->blockCache.allInCacheTrue - start->blockCache.allInCacheTrue;
  271.     if (t1 > 0) {
  272.     fprintf(stream, "Read Ahead: hits %d/%d all-in-cache %d/%d\n",
  273.             t2, t1, t4, t3);
  274.     }
  275.  
  276.     t1 = end->blockCache.writeAccesses - start->blockCache.writeAccesses +
  277.      end->blockCache.fileDescWrites - start->blockCache.fileDescWrites +
  278.      end->blockCache.indBlockWrites - start->blockCache.indBlockWrites +
  279.      end->blockCache.dirBlockWrites - start->blockCache.dirBlockWrites;
  280.     t2 = end->blockCache.partialWriteHits - start->blockCache.partialWriteHits +
  281.     end->blockCache.fileDescWriteHits - start->blockCache.fileDescWriteHits;
  282.     t3 = end->blockCache.partialWriteMisses -
  283.     start->blockCache.partialWriteMisses;
  284.     t4 = end->blockCache.blocksWrittenThru -
  285.     start->blockCache.blocksWrittenThru;
  286.     fprintf(stream, "Cache writes %d hits %d misses %d thru %d",
  287.                t1, t2, t3, t4);
  288. #ifdef stupid_compiler
  289.     if (t1 != 0) {
  290.     fprintf(stream, "\ttraffic ratio %%%d",
  291.                (int)((double)(t3+t4)/(double)t1 * 100.));
  292.     }
  293. #endif
  294.     fprintf(stream, "\n");
  295.     
  296.     fprintf(stream, "Write thru %d data %d indirect %d desc %d dir %d\n",
  297.                t4,
  298.                end->blockCache.dataBlocksWrittenThru -
  299.                start->blockCache.dataBlocksWrittenThru,
  300.                end->blockCache.indBlocksWrittenThru -
  301.                start->blockCache.indBlocksWrittenThru,
  302.                end->blockCache.descBlocksWrittenThru -
  303.                start->blockCache.descBlocksWrittenThru,
  304.                end->blockCache.dirBlocksWrittenThru -
  305.                start->blockCache.dirBlocksWrittenThru);
  306.     if (end->blockCache.fileDescReads > 0) {
  307.     fprintf(stream, "File descriptor reads %d hits %d writes %d hits %d\n",
  308.                    end->blockCache.fileDescReads -
  309.                    start->blockCache.fileDescReads,
  310.                    end->blockCache.fileDescReadHits -
  311.                    start->blockCache.fileDescReadHits,
  312.                    end->blockCache.fileDescWrites -
  313.                    start->blockCache.fileDescWrites,
  314.                    end->blockCache.fileDescWriteHits -
  315.                    start->blockCache.fileDescWriteHits);
  316.     }
  317.     if (end->blockCache.indBlockAccesses > 0) {
  318.     fprintf(stream, "Indirect block reads %d hits %d writes %d\n",
  319.                end->blockCache.indBlockAccesses -
  320.                start->blockCache.indBlockAccesses,
  321.                end->blockCache.indBlockHits -
  322.                start->blockCache.indBlockHits,
  323.                end->blockCache.indBlockWrites -
  324.                start->blockCache.indBlockWrites);
  325.     }
  326.     if (end->blockCache.dirBlockAccesses > 0) {
  327.     fprintf(stream, "Directory block reads %d hits %d writes %d\n",
  328.                    end->blockCache.dirBlockAccesses -
  329.                    start->blockCache.dirBlockAccesses,
  330.                    end->blockCache.dirBlockHits -
  331.                    start->blockCache.dirBlockHits,
  332.                    end->blockCache.dirBlockWrites -
  333.                    start->blockCache.dirBlockWrites);
  334.     }
  335.     if (end->blockCache.vmRequests > 0) {
  336.     fprintf(stream, "VM requests %d tried %d gave %d\n",
  337.                    end->blockCache.vmRequests -
  338.                    start->blockCache.vmRequests,
  339.                    end->blockCache.triedToGiveToVM -
  340.                    start->blockCache.triedToGiveToVM,
  341.                    end->blockCache.vmGotPage -
  342.                    start->blockCache.vmGotPage);
  343.     }
  344.     fprintf(stream, "Cache blocks created %d, alloc from free %d part %d lru %d\n",
  345.                    end->blockCache.unmapped -
  346.                    start->blockCache.unmapped,
  347.                    end->blockCache.totFree -
  348.                    start->blockCache.totFree,
  349.                    end->blockCache.partFree -
  350.                    start->blockCache.partFree,
  351.                    end->blockCache.lru -
  352.                    start->blockCache.lru);
  353.     if (end->alloc.blocksAllocated > 0) {
  354.     fprintf(stream, "Disk blocks alloc %d free %d search %d/%d hash %d\n",
  355.                    end->alloc.blocksAllocated -
  356.                    start->alloc.blocksAllocated,
  357.                    end->alloc.blocksFreed -
  358.                    start->alloc.blocksFreed,
  359.                    end->alloc.cylsSearched -
  360.                    start->alloc.cylsSearched,
  361.                    end->alloc.cylBitmapSearches -
  362.                    start->alloc.cylBitmapSearches,
  363.                    end->alloc.cylHashes -
  364.                    start->alloc.cylHashes);
  365.     fprintf(stream, "Fragments alloc %d free %d upgrade %d blocks made %d used %d, bad hints %d\n",
  366.                    end->alloc.fragsAllocated -
  367.                    start->alloc.fragsAllocated,
  368.                    end->alloc.fragsFreed -
  369.                    start->alloc.fragsFreed,
  370.                    end->alloc.fragUpgrades -
  371.                    start->alloc.fragUpgrades,
  372.                    end->alloc.fragToBlock -
  373.                    start->alloc.fragToBlock,
  374.                    end->alloc.fullBlockFrags -
  375.                    start->alloc.fullBlockFrags,
  376.                    end->alloc.badFragList -
  377.                    start->alloc.badFragList);
  378.     }
  379.     if (end->nameCache.accesses > 0) {
  380.     fprintf(stream, "Name cache entries %d accesses %d hits %d replaced %d\n",
  381.                end->nameCache.size,
  382.                end->nameCache.accesses -
  383.                start->nameCache.accesses,
  384.                end->nameCache.hits -
  385.                start->nameCache.hits,
  386.                end->nameCache.replacements -
  387.                start->nameCache.replacements);
  388.     }
  389.     fprintf(stream, "Handles %d created %d installed %d hits %d old %d version %d flush %d\n",
  390.                end->handle.exists,
  391.                end->handle.created -
  392.                start->handle.created,
  393.                end->handle.installCalls -
  394.                start->handle.installCalls,
  395.                end->handle.installHits -
  396.                start->handle.installHits,
  397.                0,
  398.                end->handle.versionMismatch -
  399.                start->handle.versionMismatch,
  400.                end->handle.cacheFlushes -
  401.                start->handle.cacheFlushes);
  402.     fprintf(stream, "\tfetched %d hits %d released %d locks %d/%d wait %d\n",
  403.                end->handle.fetchCalls -
  404.                start->handle.fetchCalls,
  405.                end->handle.fetchHits -
  406.                start->handle.fetchHits,
  407.                end->handle.release -
  408.                start->handle.release,
  409.                end->handle.locks -
  410.                start->handle.locks,
  411.                end->handle.locks -
  412.                start->handle.locks,
  413.                end->handle.lockWaits -
  414.                start->handle.lockWaits);
  415.     fprintf(stream, "Segments fetched %d hits %d\n",
  416.                end->handle.segmentFetches -
  417.                start->handle.segmentFetches,
  418.                end->handle.segmentHits -
  419.                start->handle.segmentHits);
  420.     fprintf(stream, "Lookup relative %d absolute %d redirect %d found %d loops %d timeouts %d stale %d\n",
  421.                end->prefix.relative -
  422.                start->prefix.relative,
  423.                end->prefix.absolute -
  424.                start->prefix.absolute,
  425.                end->prefix.redirects -
  426.                start->prefix.redirects,
  427.                end->prefix.found -
  428.                start->prefix.found,
  429.                end->prefix.loops -
  430.                start->prefix.loops,
  431.                end->prefix.timeouts -
  432.                start->prefix.timeouts,
  433.                end->prefix.stale -
  434.                start->prefix.stale);
  435. }
  436.  
  437.  
  438. /*
  439.  *----------------------------------------------------------------------
  440.  *
  441.  * PrintDiskStats --
  442.  *
  443.  *    Print out statistics for the disks.  If both a start and end
  444.  *    sample of the statistics are given then the differences between
  445.  *    the two are printed.  To just print the total cumulative statistics
  446.  *    from one sample, specify a single VmStats buffer with the 'end'
  447.  *    parameter.
  448.  *
  449.  * Results:
  450.  *    None.
  451.  *
  452.  * Side effects:
  453.  *    Prints to the specified stream
  454.  *
  455.  *----------------------------------------------------------------------
  456.  */
  457. void
  458. PrintDiskStats(stream, start, end)
  459.     FILE        *stream;    /* Output stream */
  460.     Sys_DiskStats    *start;    /* 0, or address of "before run" statistics */
  461.     Sys_DiskStats    *end;    /* End of run statistics */
  462. {
  463.     int    i = 0;
  464.     while (1) {
  465.     if (end[i].name[0] == 0) {
  466.         return;
  467.     }
  468.     if (start == 0) {
  469.         fprintf(stream, "Disk (%s, %d): %0.2f%% Idle Reads %d Writes %d\n",
  470.             end[i].name, end[i].controllerID,
  471.             100 * ((float)end[i].idleCount / (float)end[i].numSamples),
  472.             end[i].diskReads, end[i].diskWrites);
  473.     } else {
  474.         fprintf(stream, "Disk (%s, %d) %0.0f%% Idle Reads %d Writes %d\n",
  475.             end[i].name, end[i].controllerID,
  476.             100 * ((float)(end[i].idleCount - start[i].idleCount) /
  477.                    (float)(end[i].numSamples - start[i].numSamples)),
  478.             end[i].diskReads - start[i].diskReads,
  479.             end[i].diskWrites - start[i].diskWrites);
  480.     }
  481.     i++;
  482.     }
  483. }
  484.  
  485.  
  486. /*
  487.  *----------------------------------------------------------------------
  488.  *
  489.  * PrintVmStats --
  490.  *
  491.  *    Print out VM statistics.  If both a start and end
  492.  *    sample of the statistics are given then the differences between
  493.  *    the two are printed.  To just print the total cumulative statistics
  494.  *    from one sample, specify a single VmStats buffer with the 'end'
  495.  *    parameter.
  496.  *
  497.  * Results:
  498.  *    None.
  499.  *
  500.  * Side effects:
  501.  *    Prints to the specified stream
  502.  *
  503.  *----------------------------------------------------------------------
  504.  */
  505. void
  506. PrintVmStats(stream, start, end)
  507.     FILE *stream;    /* Output stream */
  508.     Vm_Stat *start;    /* 0, or address of "before run" statistics */
  509.     Vm_Stat *end;    /* End of run statistics */
  510. {
  511.     register    int    *diffPtr;
  512.     register    int    *startPtr;
  513.     register    int    *endPtr;
  514.     int            i;
  515.     int            inusePages;
  516.     int            totPages;
  517.     int            numModifiedPages;
  518.     Vm_Stat        diffStat;
  519.     int            totPercent;
  520.     int            totFaults;
  521.     int            heapPercent;
  522.     int            stkPercent;
  523.     int            quickPercent;    
  524.     int            totHits;
  525.     int            totPrefetches;
  526.     int            hitPct;
  527.  
  528.     startPtr = (int *)start;
  529.     endPtr = (int *)end;
  530.     diffPtr = (int *)&diffStat;
  531.  
  532.     for (i = 0; 
  533.          i < sizeof(Vm_Stat) / sizeof(int); 
  534.      i++, startPtr++, endPtr++, diffPtr++) {
  535.     *diffPtr = *endPtr - *startPtr;
  536.     }
  537.  
  538.     (void)Vm_Cmd(VM_COUNT_DIRTY_PAGES, &numModifiedPages);
  539.     fprintf(stream, "Kernel VM Pages: %d (Code+Data=%d Stacks=%d)\n",
  540.          end->kernMemPages + end->kernStackPages,
  541.          end->kernMemPages, end->kernStackPages);
  542.     inusePages = end->numDirtyPages + end->numUserPages;
  543.     totPages = end->numFreePages + inusePages;
  544.     fprintf(stream, "User VM Pages:   %d (Free=%d Dirty=%d Res=%d Alloc-list=%d)\n",
  545.         end->numFreePages + end->numDirtyPages + 
  546.         end->numReservePages + end->numUserPages, 
  547.         end->numFreePages, end->numDirtyPages,
  548.         end->numReservePages,
  549.         end->numUserPages);
  550.     fprintf(stream, "Modified pages: Total=%d %%Tot-dirty=%0.2f %%Inuse-dirty=%0.2f\n",
  551.         numModifiedPages,
  552.         (float) (numModifiedPages) / (float)totPages * 100.0,
  553.         (float) (numModifiedPages) / (float)inusePages * 100.0);
  554.     fprintf(stream, "FS Pages: Current=%d Max=%d Min=%d\n", 
  555.         end->fsMap - end->fsUnmap, end->maxFSPages, end->minFSPages);
  556.     fprintf(stream,
  557.          "Faults: %8d (Zero=%d FS=%d Swap=%d Quick=%d Coll=%d)\n", 
  558.          diffStat.totalFaults, diffStat.zeroFilled, diffStat.fsFilled,
  559.          diffStat.psFilled,diffStat.quickFaults, diffStat.collFaults);
  560.     fprintf(stream, "        %8d (Code=%d Heap=%d Stack=%d)\n", 
  561.          diffStat.totalFaults, diffStat.codeFaults, diffStat.heapFaults,
  562.          diffStat.stackFaults);
  563.     fprintf(stream, 
  564.         "Mod page stats:  Pot-mod=%d Not-mod=%d Not-hard-mod=%d\n",
  565.         diffStat.potModPages, diffStat.notModPages, 
  566.         diffStat.notHardModPages);
  567.  
  568.     /*
  569.      * Copy on write. 
  570.      */
  571.     totPages = diffStat.numCOWStkPages + diffStat.numCOWHeapPages;
  572.     totFaults = diffStat.numCOWStkFaults + diffStat.numCOWHeapFaults;
  573.     if (diffStat.numCOWHeapPages > 0) {
  574.     heapPercent = 100.0 * ((float)diffStat.numCOWHeapFaults / 
  575.                       diffStat.numCOWHeapPages);
  576.     } else {
  577.     heapPercent = 0;
  578.     }
  579.     if (diffStat.numCOWStkPages > 0) {
  580.     stkPercent = 100.0 * ((float)diffStat.numCOWStkFaults / 
  581.                       diffStat.numCOWStkPages);
  582.     } else {
  583.     stkPercent = 0;
  584.     }
  585.     if (totPages > 0) {
  586.     totPercent = 100.0 * ((float)totFaults / totPages);
  587.     } else {
  588.     totPercent = 0;
  589.     }
  590.     if (totFaults > 0) {
  591.     quickPercent = 100.0 * ((float)diffStat.quickCOWFaults / totFaults);
  592.     } else {
  593.     quickPercent = 0;
  594.     }
  595.     fprintf(stream, 
  596.         "COW: Heap (%d/%d)=%d%% Stk (%d/%d)=%d%% Tot (%d/%d)=%d%%\n",
  597.         diffStat.numCOWHeapFaults, diffStat.numCOWHeapPages, heapPercent,
  598.         diffStat.numCOWStkFaults, diffStat.numCOWStkPages, stkPercent,
  599.         totFaults, totPages, totPercent);
  600.     fprintf(stream, "     Quick (%d/%d)=%d%%\n",
  601.         diffStat.quickCOWFaults, totFaults, quickPercent);
  602.     /*
  603.      * Copy on reference.
  604.      */
  605.     totPages = diffStat.numCORStkPages + diffStat.numCORHeapPages;
  606.     totFaults = diffStat.numCORStkFaults + diffStat.numCORHeapFaults;
  607.     if (diffStat.numCORHeapPages > 0) {
  608.     heapPercent = 100.0 * ((float)diffStat.numCORHeapFaults / 
  609.                       diffStat.numCORHeapPages);
  610.     } else {
  611.     heapPercent = 0;
  612.     }
  613.     if (diffStat.numCORStkPages > 0) {
  614.     stkPercent = 100.0 * ((float)diffStat.numCORStkFaults / 
  615.                       diffStat.numCORStkPages);
  616.     } else {
  617.     stkPercent = 0;
  618.     }
  619.     if (totPages > 0) {
  620.     totPercent = 100.0 * ((float)totFaults / totPages);
  621.     } else {
  622.     totPercent = 0;
  623.     }
  624.     fprintf(stream,
  625.             "COR: Heap (%d/%d)=%d%% Stk (%d/%d)=%d%% Tot (%d/%d)=%d%%\n",
  626.         diffStat.numCORHeapFaults, diffStat.numCORHeapPages, heapPercent,
  627.         diffStat.numCORStkFaults, diffStat.numCORStkPages, stkPercent,
  628.         totFaults, totPages, totPercent);
  629.     totPages = diffStat.numCORStkFaults + diffStat.numCORHeapFaults;
  630.     totFaults = diffStat.numCORCOWStkFaults + diffStat.numCORCOWHeapFaults;
  631.     if (diffStat.numCORCOWHeapFaults > 0) {
  632.     heapPercent = 100.0 * ((float)diffStat.numCORCOWHeapFaults / 
  633.                       diffStat.numCORHeapFaults);
  634.     } else {
  635.     heapPercent = 0;
  636.     }
  637.     if (diffStat.numCORCOWStkFaults > 0) {
  638.     stkPercent = 100.0 * ((float)diffStat.numCORCOWStkFaults / 
  639.                       diffStat.numCORStkFaults);
  640.     } else {
  641.     stkPercent = 0;
  642.     }
  643.     if (totPages > 0) {
  644.     totPercent = 100.0 * ((float)totFaults / totPages);
  645.     } else {
  646.     totPercent = 0;
  647.     }
  648.     fprintf(stream,
  649.             "COR-mod: Heap(%d/%d)=%d%% Stk (%d/%d)=%d%% Tot (%d/%d)=%d%%\n",
  650.         diffStat.numCORCOWHeapFaults, diffStat.numCORHeapFaults,heapPercent,
  651.         diffStat.numCORCOWStkFaults, diffStat.numCORStkFaults, stkPercent,
  652.         diffStat.numCORCOWHeapFaults + diffStat.numCORCOWStkFaults,
  653.         diffStat.numCORHeapFaults + diffStat.numCORStkFaults, totPercent);
  654.  
  655.     fprintf(stream, "Swap pages copied: %d\n", diffStat.swapPagesCopied);
  656.     fprintf(stream,
  657.              "Vm allocs: %d (Free=%d From-FS=%d From-alloc-list=%d)\n",
  658.          diffStat.numAllocs, diffStat.gotFreePage, diffStat.gotPageFromFS, 
  659.          diffStat.pageAllocs);
  660.     fprintf(stream, 
  661.          "VM-FS stats: Asked=%d Free-pages=%d Allocs=%d Frees=%d\n",
  662.          diffStat.fsAsked, diffStat.haveFreePage, diffStat.fsMap, 
  663.          diffStat.fsUnmap);
  664.     fprintf(stream, "Alloc-list searches: %d (Free=%d In-use=%d)\n",
  665.          diffStat.numListSearches, diffStat.usedFreePage, 
  666.          diffStat.numListSearches - diffStat.usedFreePage);
  667.     fprintf(stream, "Extra-searches: %d (Lock=%d Ref=%d Dirty=%d)\n",
  668.          diffStat.lockSearched + diffStat.refSearched + 
  669.          diffStat.dirtySearched,
  670.          diffStat.lockSearched, diffStat.refSearched, 
  671.          diffStat.dirtySearched);
  672.     fprintf(stream, "Pages written %d\n", diffStat.pagesWritten);
  673.  
  674.     totPrefetches = diffStat.codePrefetches + diffStat.heapFSPrefetches +
  675.             diffStat.heapSwapPrefetches + diffStat.stackPrefetches;
  676.     if (totPrefetches > 0) {
  677.     totHits = diffStat.codePrefetchHits + diffStat.heapFSPrefetchHits +
  678.           diffStat.heapSwapPrefetchHits + diffStat.stackPrefetchHits;
  679.     fprintf(stream, "Prefetch stats:\n");
  680.     if (diffStat.codePrefetches > 0) {
  681.         hitPct = 100 * ((float)diffStat.codePrefetchHits / 
  682.                 (float)diffStat.codePrefetches);
  683.         fprintf(stream, "    code (%d/%d)=%d%%\n",
  684.             diffStat.codePrefetchHits, diffStat.codePrefetches, hitPct);
  685.     }
  686.     if (diffStat.heapFSPrefetches > 0) {
  687.         hitPct = 100 * ((float)diffStat.heapFSPrefetchHits / 
  688.                 (float)diffStat.heapFSPrefetches);
  689.         fprintf(stream, "    heap-fs (%d/%d)=%d%%\n",
  690.         diffStat.heapFSPrefetchHits, diffStat.heapFSPrefetches, hitPct);
  691.     }
  692.     if (diffStat.heapSwapPrefetches > 0) {
  693.         hitPct = 100 * ((float)diffStat.heapSwapPrefetchHits / 
  694.                 (float)diffStat.heapSwapPrefetches);
  695.         fprintf(stream, "    heap-swp (%d/%d)=%d%%\n",
  696.         diffStat.heapSwapPrefetchHits, diffStat.heapSwapPrefetches, 
  697.         hitPct);
  698.     }
  699.     if (diffStat.stackPrefetches > 0) {
  700.         hitPct = 100 * ((float)diffStat.stackPrefetchHits / 
  701.                 (float)diffStat.stackPrefetches);
  702.         fprintf(stream, "    stack (%d/%d)=%d%%\n",
  703.         diffStat.stackPrefetchHits, diffStat.stackPrefetches, hitPct);
  704.     }
  705.     hitPct = 100 * ((float)totHits / (float)totPrefetches);
  706.     fprintf(stream, "    total (%d/%d)=%d%%\n",
  707.         totHits, totPrefetches, hitPct);
  708.     fprintf(stream, "    aborts=   %d\n", diffStat.prefetchAborts);
  709.     }
  710.  
  711.  
  712.     fprintf(stream, "Contexts stolen %d pmegs stolen %d\n",
  713.          diffStat.machDepStat.stealContext, diffStat.machDepStat.stealPmeg);
  714. }
  715.  
  716.  
  717.  
  718. /*
  719.  *----------------------------------------------------------------------
  720.  *
  721.  * PrintIntervalStats --
  722.  *
  723.  *    Print out values over intervals.  For now, only idle time
  724.  *    is printed, plus a smattering of other things.
  725.  *
  726.  * Results:
  727.  *    None.
  728.  *
  729.  * Side effects:
  730.  *    Prints to the s
  731.  *
  732.  *----------------------------------------------------------------------
  733.  */
  734. void
  735. PrintIntervalStats(stream, intervals, fsArray,
  736.            vmArray, diskArray, schedArray, netArray)
  737.     FILE *stream;
  738.     int intervals;
  739.     Fs_Stats *fsArray;
  740.     Vm_Stat *vmArray;
  741.     Sys_DiskStats *diskArray;
  742.     Sched_Instrument *schedArray;
  743.     Net_EtherStats *netArray;
  744. {
  745.     int i;
  746.     Sched_Instrument *startSchedPtr, *endSchedPtr;
  747.     Net_EtherStats *startNetPtr, *endNetPtr;
  748.     double     lowTicks;
  749.     extern int repeatInterval;
  750.  
  751.     fprintf(stream, "Interval measurements of idle ticks:\n");
  752.     startSchedPtr = &schedArray[0];
  753.     endSchedPtr = &schedArray[0];
  754.     for (i = 0; i < intervals; i++) {
  755.     endSchedPtr++;
  756.         lowTicks = endSchedPtr->processor[0].idleTicksLow 
  757.         - startSchedPtr->processor[0].idleTicksLow;
  758.     lowTicks /= repeatInterval;
  759.     fprintf(stream, "%d %0.0f\n", i, lowTicks);
  760.     startSchedPtr++;
  761.     }
  762.  
  763.  
  764.     fprintf(stream, "Interval measurements of network traffic (in, out):\n");
  765.     startNetPtr = &netArray[0];
  766.     endNetPtr = &netArray[0];
  767.     for (i = 0; i < intervals; i++) {
  768.     endNetPtr++;
  769.     fprintf(stream, "%d %u %u\n", i, 
  770.         endNetPtr->bytesReceived - startNetPtr->bytesReceived,
  771.             endNetPtr->bytesSent - startNetPtr->bytesSent);
  772.     startNetPtr++;
  773.     }
  774. }
  775.  
  776.